﻿using KwaiXiaoDian.Entity.Common;
using KwaiXiaoDian.Entity.DO;
using KwaiXiaoDian.Entity.VO.Product;
using KwaiXiaoDian.Entity.VO.Notice;
using KwaiXiaoDian.IDao;
using KwaiXiaoDian.IService;
using Microsoft.Extensions.Logging;
using SSharing.Frameworks.NetCore.Common.Extends;
using System;
using System.Linq;
using System.Collections.Generic;
using System.Text;
using Microsoft.Extensions.Configuration;
using SSharing.Frameworks.NetCore.Common.Results;
using SSharing.Frameworks.NetCore.Common.Consts;
using System.Diagnostics;
using System.Linq.Expressions;
using System.Data;
using SSharing.Frameworks.NetCore.Document;
using System.IO;
using Microsoft.Extensions.Caching.Memory;

namespace KwaiXiaoDian.Service
{
    /// <summary>
    /// 商品service
    /// </summary>
    public class ProductService : BaseService<TProduct>, IProductService
    {
        private readonly IProductDao _productDao;
        private readonly IGroupLeaderDao _groupLeaderDao;
        private readonly ILogger<ProductService> _logger;
        private readonly IKwaiXiaoDianService _kwaiXiaoDianService;
        private readonly INoticeService _noticeService;
        private readonly IConfiguration _configuration;
        private readonly IProductExpressDao _productExpressDao;
        private readonly IProductShopDao _productShopDao;
        private readonly IProductRankDao _productRankDao;
        private readonly IChannelDao _channelDao;
        private readonly IChannelService _channelService;
        private readonly IDocument _document;
        private readonly IProductPromoteDao _productPromoteDao;
        private readonly IMemoryCache _memoryCache;

        public ProductService(IProductDao productDao
            , IGroupLeaderDao groupLeaderDao
            , ILogger<ProductService> logger
            , IKwaiXiaoDianService kwaiXiaoDianService
            , INoticeService noticeService
            , IConfiguration configuration
            , IProductExpressDao productExpressDao
            , IProductShopDao productShopDao
            , IProductRankDao productRankDao
            , IChannelDao channelDao
            , IChannelService channelService
            , IDocument document
            , IProductPromoteDao productPromoteDao
            , IMemoryCache memoryCache) : base(productDao)
        {
            _productDao = productDao;
            _groupLeaderDao = groupLeaderDao;
            _logger = logger;
            _kwaiXiaoDianService = kwaiXiaoDianService;
            _noticeService = noticeService;
            _configuration = configuration;
            _productExpressDao = productExpressDao;
            _productShopDao = productShopDao;
            _productRankDao = productRankDao;
            _channelDao = channelDao;
            _channelService = channelService;
            _document = document;
            _productPromoteDao = productPromoteDao;
            _memoryCache = memoryCache;
        }

        /// <summary>
        /// 同步商品信息
        /// </summary>
        /// <returns></returns>
        public bool Sync()
        {
            bool syncSuccess = false;
            var now = DateTime.Now;
            StringBuilder sbLog = new StringBuilder("开始同步商品信息，");
            Stopwatch stopwatch = Stopwatch.StartNew();
            long homeChannelId = 99;

            //读取配置
            var isNewProductNotice = _configuration["IsNewProductNotice"].ToBool(false);

            //从本地获取团长列表
            var groupLeaders = _groupLeaderDao.Get(p => p.IsEnabled == Enums.IsEnabledType.Y.ToString()).ToList();
            if (!groupLeaders.HasValue())
            {
                sbLog.AppendFormat("无团长.");
                _logger.LogInformation(sbLog.ToString());

                return syncSuccess;
            }
            sbLog.AppendFormat("共：{0}个团长，", groupLeaders.Count);

            //获取Channel列表，获取首页Channel
            var homeChannel = _channelDao.Get(p => p.IsEnabled == Enums.IsEnabledType.Y.ToString() && p.ChannelName == "首页").FirstOrDefault();
            if (homeChannel != null)
            {
                homeChannelId = homeChannel.ChannelId.HasValue ? homeChannel.ChannelId.Value : 99;
            }

            //遍历依据团长id获取该团长的全部商品信息
            sbLog.AppendFormat("开始同步团长的商品信息，");
            int getProductInfoErrorTimes = 0;
            foreach (var groupLeader in groupLeaders)
            {
                try
                {
                    var leaderId = groupLeader.LeaderId;
                    var leaderName = groupLeader.Name;

                    //快小店团长的全部商品列表
                    var getProductInfoResult = _kwaiXiaoDianService.GetProductInfo(leaderId);

                    //Cookie失败时通知管理员，并且不会删除本地商品数据
                    if (!getProductInfoResult.IsSuccess)
                    {
                        //连续超过3次则不再发送微信通知
                        if (getProductInfoErrorTimes > 3)
                        {
                            break;
                        }

                        _noticeService.SendServerChan(new SendServerChanRequest
                        {
                            Text = "同步商品信息时发生异常!",
                            Desp = getProductInfoResult.ErrorMessage
                        }, isOnlyAdmin: true);

                        getProductInfoErrorTimes++;
                        continue;
                    }
                    var apiProducts = getProductInfoResult.Data;

                    //接口没有数据或接口异常时直接跳过
                    if (!apiProducts.HasValue())
                    {
                        continue;
                    }

                    //本地数据库团长的全部商品列表
                    var dbProducts = _productDao.Get(p => p.LeaderId == leaderId).ToList();

                    //待新增列表，apiProducts-dbProducts
                    var addingProducts = new List<TProduct>();

                    //存在的则更新，不存在则新增
                    var i = 0;
                    var j = 0;
                    foreach (var apiProduct in apiProducts)
                    {
                        var dbProduct = _productDao.Get(p => p.LeaderId == apiProduct.LeaderId && p.ProductId == apiProduct.ProductId).FirstOrDefault();
                        if (dbProduct != null)
                        {
                            dbProduct.LastUpdatedBy = -1;
                            dbProduct.LastUpdatedTime = now;
                            dbProduct.Name = apiProduct.Name;
                            dbProduct.ImageUrl = apiProduct.ImageUrl;
                            dbProduct.Price = apiProduct.Price;
                            dbProduct.ProfitAmount = apiProduct.ProfitAmount;
                            dbProduct.CommissionRate = apiProduct.CommissionRate;
                            dbProduct.DeliveryTime = apiProduct.DeliveryTime;
                            dbProduct.PromoterNum = apiProduct.PromoterNum;
                            dbProduct.SoldCountThirtyDays = apiProduct.SoldCountThirtyDays;
                            dbProduct.DistributeItemId = apiProduct.DistributeItemId;
                            dbProduct.Status = (byte)Enums.ProductStatusType.OnStock;
                            _productDao.Update(dbProduct);
                            j++;
                        }
                        else
                        {
                            //设置商品类别Job不处理首页类别，首页类别在商品落地的时候设置
                            apiProduct.Channel = "," + homeChannelId + ",";
                            addingProducts.Add(apiProduct);
                            i++;
                        }
                    }
                    if (addingProducts.HasValue())
                    {
                        _productDao.Add(addingProducts);
                    }

                    //下架商品列表，dbProducts-apiProducts
                    var offStockProducts = dbProducts.Except(apiProducts, new ProductEqualityComparer()).ToList();
                    if (offStockProducts.HasValue())
                    {
                        foreach (var offStockProduct in offStockProducts)
                        {
                            offStockProduct.Status = (byte)Enums.ProductStatusType.OffStock;
                            offStockProduct.LastUpdatedBy = -1;
                            offStockProduct.LastUpdatedTime = now;
                            _productDao.Update(offStockProduct);
                        }
                    }

                    //记录同步日志
                    sbLog.AppendFormat("团长Id：{0}，团长名称：{1}，新增：{2}个，更新：{3}个，下架：{4}个，", leaderId, leaderName, i, j, offStockProducts.Count);

                    //发送微信提醒，团长上新商品信息
                    var isNotice = addingProducts.HasValue() && isNewProductNotice;
                    if (isNotice)
                    {
                        List<string> markdownHeaders = new List<string> { "商品Id", "名称", "价格", "佣金率", "利润", "图片" };
                        List<List<string>> markdownData = new List<List<string>>();
                        foreach (var addingProduct in addingProducts)
                        {
                            var price = addingProduct.Price.HasValue ? addingProduct.Price.Value.ToString("F2") : "";
                            var commissionRate = addingProduct.CommissionRate.HasValue ? addingProduct.CommissionRate.Value.ToString("P2") : "";
                            var profitAmount = addingProduct.ProfitAmount.HasValue ? addingProduct.ProfitAmount.Value.ToString("F2") : "";
                            var imageUrl = string.Format("![替代文本]({0})", addingProduct.ImageUrl);
                            markdownData.Add(new List<string> { addingProduct.ProductId, addingProduct.Name, price, commissionRate, profitAmount, imageUrl });
                        }
                        var markdownTable = GenerateMarkdownTable(markdownHeaders, markdownData);
                        _noticeService.SendServerChan(new SendServerChanRequest
                        {
                            Text = string.Format("团长：{0}，Id：{1}，有新商品上架啦！", leaderName, leaderId),
                            Desp = markdownTable
                        });
                    }
                }
                catch (Exception ex)
                {
                    _logger.LogError(ex, string.Format("同步团长的商品信息时发生异常，团长id：{0}，团长名称：{1}，message:{2}", groupLeader.LeaderId, groupLeader.Name, ex.Message));
                }
            }
            stopwatch.Stop();
            sbLog.AppendFormat("全部同步完成，共耗时：{0}秒！", stopwatch.ElapsedMilliseconds / 1000);
            _logger.LogInformation(sbLog.ToString());

            syncSuccess = true;
            return syncSuccess;
        }

        /// <summary>
        /// 获取商品列表
        /// </summary>
        /// <param name="request"></param>
        /// <returns></returns>
        public IPagingResult<Product> GetPagingProducts(GetPagingProductsRequest request)
        {
            List<Product> list = new List<Product>();
            var pagingProducts = _productDao.GetPagingProducts(request);
            if (pagingProducts == null || !pagingProducts.Entities.HasValue())
            {
                return new PagingResult<Product>(pagingProducts.TotalCount, request.Page, request.Limit, list);
            }

            foreach (var item in pagingProducts.Entities)
            {
                var commissionRate = "";
                var channelName = "";

                //佣金率
                if (item.CommissionRate.HasValue)
                {
                    commissionRate = item.CommissionRate.Value.ToString("P2");
                }

                //商品类别
                if (!item.Channel.IsNullOrEmpty())
                {
                    var channelIds = item.Channel.Split(new string[] { "," }, StringSplitOptions.RemoveEmptyEntries).Select(p => Convert.ToInt64(p)).ToList();

                    //依据channelId返回channel列表，并且按sort升序排序
                    var channelList = _channelService.GetByChannelIds(channelIds);
                    channelName = string.Join(",", channelList.Select(p => p.ChannelName));
                }

                list.Add(new Product
                {
                    Id = item.Id,
                    CreatedTime = item.CreatedTime.ToString(DateTimeTypeConst.DATETIME),
                    LeaderId = item.LeaderId,
                    LeaderName = item.LeaderName,
                    ProductId = item.ProductId,
                    ProductName = item.Name,
                    ImageUrl = item.ImageUrl,
                    Price = item.Price.HasValue ? item.Price.Value.ToString("F2") : "",
                    ProfitAmount = item.ProfitAmount.HasValue ? item.ProfitAmount.Value.ToString("F2") : "",
                    CommissionRate = commissionRate,
                    PromoterNum = item.PromoterNum.HasValue ? item.PromoterNum.Value.ToString() : "",
                    SoldCountThirtyDays = item.SoldCountThirtyDays.HasValue ? item.SoldCountThirtyDays.Value.ToString() : "",
                    DistributeItemId = item.DistributeItemId,
                    Status = item.Status.HasValue ? item.Status.Value.ToString() : "",
                    StatusName = item.Status.HasValue ? item.Status.Value.ToEnum<Enums.ProductStatusType>().GetDescription() : "",
                    ChannelName = channelName,
                    HandleStatus = item.HandleStatus.HasValue ? item.HandleStatus.Value.ToString() : "",
                    HandleStatusName = item.HandleStatus.HasValue ? item.HandleStatus.Value.ToEnum<Enums.HandleStatusType>().GetDescription() : "",
                    Remark = item.Remark
                });
            }

            return new PagingResult<Product>(pagingProducts.TotalCount, request.Page, request.Limit, list);
        }

        /// <summary>
        /// 同步商品详情，包括商品店铺信息，商品物流信息
        /// </summary>
        /// <returns></returns>
        public bool SyncProductDetail()
        {
            bool syncProductDetailSuccess = false;
            var now = DateTime.Now;
            StringBuilder sbLog = new StringBuilder("开始同步商品详情，");
            Stopwatch stopwatch = Stopwatch.StartNew();

            //获取待同步商品列表
            var productDetails = _productDao.GetProductDetails();
            if (!productDetails.HasValue())
            {
                sbLog.AppendFormat("无待同步的商品数据.");
                _logger.LogInformation(sbLog.ToString());

                return syncProductDetailSuccess;
            }
            sbLog.AppendFormat("共：{0}个商品，", productDetails.Count);
            sbLog.AppendFormat("开始同步商品详情，");

            //每次同步1000个商品，可配置
            var perTimesCount = _configuration["Product.SyncProductDetail.PerTimesCount"].ToInt(1000);
            int i = 0;
            int getProductDetailInfoErrorTimes = 0;
            foreach (var productDetail in productDetails)
            {
                var productId = productDetail.ProductId;
                var distributeItemId = productDetail.DistributeItemId;
                try
                {
                    //每次同步1000个商品
                    if (i >= perTimesCount)
                    {
                        break;
                    }

                    var getProductDetailInfoResult = _kwaiXiaoDianService.GetProductDetailInfo(distributeItemId, millisecondsTimeout: 3000);
                    if (!getProductDetailInfoResult.IsSuccess)
                    {
                        //连续超过3次则不再发送微信通知
                        if (getProductDetailInfoErrorTimes > 3)
                        {
                            break;
                        }

                        _noticeService.SendServerChan(new SendServerChanRequest
                        {
                            Text = "同步商品详情时发生异常!",
                            Desp = getProductDetailInfoResult.ErrorMessage
                        }, isOnlyAdmin: true);

                        getProductDetailInfoErrorTimes++;
                        continue;
                    }

                    Mtp_Storeentrance_Njfhtgf7qks5atfq storeInfo = new Mtp_Storeentrance_Njfhtgf7qks5atfq();//店铺信息

                    var jObj = getProductDetailInfoResult.Data.data.data;
                    foreach (var item in jObj)
                    {
                        if (item.Key.Contains("mtp_storeEntrance"))
                        {
                            storeInfo = item.Value.ToObject<Mtp_Storeentrance_Njfhtgf7qks5atfq>();
                        }
                    }

                    //平台下架的商品本地不删除，包括商品详情（物流和店铺信息）和达人排行榜数据
                    if (storeInfo != null && storeInfo.fields != null && storeInfo.fields.shopInfo != null && storeInfo.fields.shopInfo.shopId == 0)
                    {
                        continue;
                    }

                    //商品店铺信息，不存在则新增，存在则更新
                    var shopInfo = storeInfo.fields.shopInfo;
                    Storescoreinfo summaryScoreInfo = shopInfo.storeScoreInfo;
                    var productScoreInfo = shopInfo.storeScoreInfo.storeScoreQuadrantList.FirstOrDefault(p => p.name == "商品体验");
                    var expressScoreInfo = shopInfo.storeScoreInfo.storeScoreQuadrantList.FirstOrDefault(p => p.name == "物流体验");
                    var serviceScoreInfo = shopInfo.storeScoreInfo.storeScoreQuadrantList.FirstOrDefault(p => p.name == "售后服务");

                    var productShop = _productShopDao.Get(p => p.ProductId == productId).FirstOrDefault();
                    if (productShop == null)
                    {
                        _productShopDao.Add(new TProductShop
                        {
                            CreatedBy = -1,
                            CreatedTime = now,
                            LastUpdatedBy = -1,
                            LastUpdatedTime = now,
                            ProductId = productId,
                            ShopId = shopInfo.shopId.ToString(),
                            ShopName = shopInfo.shopName,
                            ShopIconUrl = shopInfo.shopIconUrl,
                            DistributeSoldAmount = shopInfo.distributeSoldAmount.ToIntOrNull(),
                            SoldAmountTabText = shopInfo.soldAmountTabText,
                            SummaryScore = summaryScoreInfo.score.ToDecimalOrNull(),
                            SummaryRank = summaryScoreInfo.rank.ToString("0.00").ToDecimalOrNull(),
                            SummaryLevel = summaryScoreInfo.level,
                            ProductScore = productScoreInfo != null ? productScoreInfo.score.ToDecimalOrNull() : null,
                            ProductLevel = productScoreInfo != null ? productScoreInfo.level : "",
                            ExpressScore = expressScoreInfo != null ? expressScoreInfo.score.ToDecimalOrNull() : null,
                            ExpressLevel = expressScoreInfo != null ? expressScoreInfo.level : "",
                            ServiceScore = serviceScoreInfo != null ? serviceScoreInfo.score.ToDecimalOrNull() : null,
                            ServiceLevel = serviceScoreInfo != null ? serviceScoreInfo.level : ""
                        });
                    }
                    else
                    {
                        productShop.LastUpdatedBy = -1;
                        productShop.LastUpdatedTime = now;
                        productShop.ShopId = shopInfo.shopId.ToString();
                        productShop.ShopName = shopInfo.shopName;
                        productShop.ShopIconUrl = shopInfo.shopIconUrl;
                        productShop.DistributeSoldAmount = shopInfo.distributeSoldAmount.ToIntOrNull();
                        productShop.SoldAmountTabText = shopInfo.soldAmountTabText;
                        productShop.SummaryScore = summaryScoreInfo.score.ToDecimalOrNull();
                        productShop.SummaryLevel = summaryScoreInfo.level;
                        productShop.SummaryRank = summaryScoreInfo.rank.ToString("0.00").ToDecimalOrNull();
                        productShop.ProductScore = productScoreInfo != null ? productScoreInfo.score.ToDecimalOrNull() : null;
                        productShop.ProductLevel = productScoreInfo != null ? productScoreInfo.level : "";
                        productShop.ExpressScore = expressScoreInfo != null ? expressScoreInfo.score.ToDecimalOrNull() : null;
                        productShop.ExpressLevel = expressScoreInfo != null ? expressScoreInfo.level : "";
                        productShop.ServiceScore = serviceScoreInfo != null ? serviceScoreInfo.score.ToDecimalOrNull() : null;
                        productShop.ServiceLevel = serviceScoreInfo != null ? serviceScoreInfo.level : "";
                        _productShopDao.Update(productShop);
                    }

                    i++;
                }
                catch (Exception ex)
                {
                    _logger.LogError(ex, string.Format("同步商品详情时发生异常，商品Id：{0}，message：{1}", productId, ex.Message));
                }
            }
            stopwatch.Stop();
            sbLog.AppendFormat("全部同步完成，该次共同步：{1}个商品，共耗时：{0}秒！", stopwatch.ElapsedMilliseconds / 1000, i);
            _logger.LogInformation(sbLog.ToString());

            syncProductDetailSuccess = true;
            return syncProductDetailSuccess;
        }

        /// <summary>
        /// 同步商品达人排行榜
        /// </summary>
        /// <returns></returns>
        public bool SyncProductRank()
        {
            bool syncProductRankSuccess = false;
            var now = DateTime.Now;
            StringBuilder sbLog = new StringBuilder("开始同步商品达人排行榜，");
            Stopwatch stopwatch = Stopwatch.StartNew();

            //1，从本地获取待同步的商品列表，查询条件：全部（团长状态为启用）
            //2，调用快小店api获取商品达人排行榜信息
            //3，保存商品达人排行榜记录，先删除再新增
            var productRanks = _productDao.GetProductRanks();
            if (!productRanks.HasValue())
            {
                sbLog.AppendFormat("无待同步的商品数据.");
                _logger.LogInformation(sbLog.ToString());

                return syncProductRankSuccess;
            }
            sbLog.AppendFormat("共：{0}个商品，", productRanks.Count);
            sbLog.AppendFormat("开始同步商品达人排行榜，");

            foreach (var productRank in productRanks)
            {
                var productId = productRank.ProductId;
                var distributeItemId = productRank.DistributeItemId;
                try
                {
                    var getProductRankInfoResult = _kwaiXiaoDianService.GetProductRankInfo(distributeItemId, productId);
                    if (!getProductRankInfoResult.IsSuccess)
                    {
                        _noticeService.SendServerChan(new SendServerChanRequest
                        {
                            Text = "同步达人排行榜时发生异常!",
                            Desp = getProductRankInfoResult.ErrorMessage
                        }, isOnlyAdmin: true);
                        continue;
                    }

                    //3，保存商品达人排行榜记录，先删除再新增
                    if (getProductRankInfoResult.Data.HasValue())
                    {
                        _productRankDao.Remove(p => p.ProductId == productId);

                        var ranks = getProductRankInfoResult.Data.ToList();
                        _productRankDao.Add(ranks);
                    }
                }
                catch (Exception ex)
                {
                    _logger.LogError(ex, string.Format("同步商品达人排行榜时发生异常，商品Id：{0}，Message：{1}", productId, ex.Message));
                }
            }
            stopwatch.Stop();
            sbLog.AppendFormat("全部同步完成，共耗时：{0}秒！", stopwatch.ElapsedMilliseconds / 1000);
            _logger.LogInformation(sbLog.ToString());

            syncProductRankSuccess = true;
            return syncProductRankSuccess;
        }

        /// <summary>
        /// 获取商品名称
        /// </summary>
        /// <param name="productId"></param>
        /// <returns></returns>
        public string GetProductName(string productId)
        {
            var productName = "";

            var product = _productDao.Get(p => p.ProductId == productId).FirstOrDefault();
            if (product != null)
            {
                productName = product.Name;
            }

            return productName;
        }

        /// <summary>
        /// 设置商品类别
        /// </summary>
        /// <returns></returns>
        public bool SetProductChannel()
        {
            var setProductChannelSuccess = false;
            var now = DateTime.Now;
            StringBuilder sbLog = new StringBuilder("开始设置商品类别，");
            Stopwatch stopwatch = Stopwatch.StartNew();

            //从本地获取团长列表
            var groupLeaders = _groupLeaderDao.Get(p => p.IsEnabled == Enums.IsEnabledType.Y.ToString()).ToList();
            if (!groupLeaders.HasValue())
            {
                sbLog.AppendFormat("无团长信息.");
                _logger.LogInformation(sbLog.ToString());

                return setProductChannelSuccess;
            }
            sbLog.AppendFormat("共：{0}个团长，", groupLeaders.Count);

            //获取channel列表
            var channels = _channelDao.Get(p => p.IsEnabled == Enums.IsEnabledType.Y.ToString()).ToList();
            if (!channels.HasValue())
            {
                sbLog.AppendFormat("无Channel列表.");
                _logger.LogInformation(sbLog.ToString());

                return setProductChannelSuccess;
            }
            channels = channels.OrderBy(p => p.Sort).ToList();
            int getProductInfoErrorTimes = 0;
            bool shouldBreak = false;
            foreach (var groupLeader in groupLeaders)
            {
                foreach (var channel in channels)
                {
                    //为每个团长的商品设置类别
                    var leaderId = groupLeader.LeaderId;
                    var leaderName = groupLeader.Name;
                    var channelId = (long)channel.ChannelId;
                    var channelName = channel.ChannelName;

                    try
                    {
                        //设置商品类别Job不处理首页类别，首页类别在商品落地的时候设置
                        var isHomeChannel = channelName == "首页";
                        if (isHomeChannel)
                        {
                            continue;
                        }

                        //依据channelId获取团长的商品列表
                        var getProductInfoResult = _kwaiXiaoDianService.GetProductInfo(leaderId, channelId, 3000);

                        //Cookie失败时通知管理员
                        if (!getProductInfoResult.IsSuccess)
                        {
                            //连续超过3次则不再发送微信通知
                            if (getProductInfoErrorTimes > 3)
                            {
                                shouldBreak = true;
                                break;
                            }

                            _noticeService.SendServerChan(new SendServerChanRequest
                            {
                                Text = "设置商品类别时发生异常!",
                                Desp = getProductInfoResult.ErrorMessage
                            }, isOnlyAdmin: true);

                            getProductInfoErrorTimes++;
                            break;
                        }
                        var apiProducts = getProductInfoResult.Data;

                        //保存商品类别
                        var i = 0;
                        foreach (var apiProduct in apiProducts)
                        {
                            List<long> productChannelList = new List<long>();
                            var dbProduct = _productDao.Get(p => p.LeaderId == leaderId && p.ProductId == apiProduct.ProductId).FirstOrDefault();
                            if (dbProduct == null)
                            {
                                continue;
                            }

                            var channelStr = dbProduct.Channel;
                            if (!channelStr.IsNullOrEmpty())
                            {
                                productChannelList = channelStr.Split(new string[] { "," }, StringSplitOptions.RemoveEmptyEntries).Select(p => Convert.ToInt64(p)).ToList();
                            }

                            var isExistChannel = productChannelList.Contains(channelId);
                            if (isExistChannel)
                            {
                                continue;
                            }

                            productChannelList.Add(channelId);
                            var newChannelStr = "," + string.Join(",", productChannelList) + ",";
                            dbProduct.Channel = newChannelStr;
                            dbProduct.LastUpdatedBy = -1;
                            dbProduct.LastUpdatedTime = now;
                            _productDao.Update(dbProduct);
                            i++;
                        }

                        //记录日志
                        sbLog.AppendFormat("团长Id：{0}，团长名称：{1}，ChannelId：{2}，ChannelName：{3}，更新：{4}个商品，", leaderId, leaderName, channelId, channelName, i);
                    }
                    catch (Exception ex)
                    {
                        _logger.LogError(ex, string.Format("设置商品类别时发生异常，团长id：{0}，团长名称：{1}，ChannelId：{2}，ChannelName：{3}，message:{4}", groupLeader.LeaderId, groupLeader.Name, channelId, channelName, ex.Message));
                    }
                }
                if (shouldBreak)
                {
                    break;
                }
            }
            stopwatch.Stop();
            sbLog.AppendFormat("全部设置完成，共耗时：{0}秒！", stopwatch.ElapsedMilliseconds / 1000);
            _logger.LogInformation(sbLog.ToString());

            setProductChannelSuccess = true;
            return setProductChannelSuccess;
        }

        /// <summary>
        /// 初始化商品类别
        /// </summary>
        /// <returns></returns>
        public Tuple<bool, string> InitProductChannel()
        {
            bool initSuccess = false;
            var errorMessage = string.Empty;
            var now = DateTime.Now;
            StringBuilder sbLog = new StringBuilder("开始初始化商品类别，");
            Stopwatch stopwatch = Stopwatch.StartNew();

            //获取全部商品列表
            var allProducts = _productDao.Get(p => true).ToList();
            if (!allProducts.HasValue())
            {
                errorMessage = "无商品信息.";
                return new Tuple<bool, string>(initSuccess, errorMessage);
            }

            //获取首页channel
            var homeChannel = _channelDao.Get(p => p.ChannelName == "首页").FirstOrDefault();
            if (homeChannel == null)
            {
                errorMessage = "无首页Channel.";
                return new Tuple<bool, string>(initSuccess, errorMessage);
            }

            sbLog.AppendFormat("共获取到：{0}个商品，", allProducts.Count);
            var homeChannelId = (long)homeChannel.ChannelId;
            var i = 0;
            var j = 0;
            foreach (var product in allProducts)
            {
                //检查当前商品是否已包含首页类别，没有的话则新增
                List<long> productChannelList = new List<long>();
                try
                {
                    var channelStr = product.Channel;
                    if (channelStr.IsNullOrEmpty())
                    {
                        productChannelList.Add(homeChannelId);
                        var newChannelStr = "," + string.Join(",", productChannelList) + ",";
                        product.Channel = newChannelStr;
                        product.LastUpdatedBy = -1;
                        product.LastUpdatedTime = now;
                        _productDao.Update(product);
                        i++;
                        continue;
                    }

                    productChannelList = channelStr.Split(new string[] { "," }, StringSplitOptions.RemoveEmptyEntries).Select(p => Convert.ToInt64(p)).ToList();
                    var isExistHomeChannel = productChannelList.Contains(homeChannelId);
                    if (!isExistHomeChannel)
                    {
                        productChannelList.Add(homeChannelId);
                        var newChannelStr = "," + string.Join(",", productChannelList) + ",";
                        product.Channel = newChannelStr;
                        product.LastUpdatedBy = -1;
                        product.LastUpdatedTime = now;
                        _productDao.Update(product);
                        j++;
                        continue;
                    }
                }
                catch (Exception ex)
                {
                    _logger.LogError(ex, string.Format("初始化商品类别时发生异常，message：{0}", ex.Message));
                }
            }
            stopwatch.Stop();
            sbLog.AppendFormat("全部完成，首次设置首页类别商品数量：{0}个，更新设置首页类别商品数量：{1}个，共耗时：{2}秒！", i, j, stopwatch.ElapsedMilliseconds / 1000);
            _logger.LogInformation(sbLog.ToString());

            initSuccess = true;
            return new Tuple<bool, string>(initSuccess, errorMessage);
        }

        /// <summary>
        /// 查询导出的字段列表
        /// </summary>
        /// <returns></returns>
        public IList<ExportField> GetExportFields()
        {
            IList<ExportField> items = new List<ExportField>();

            var names = Consts.ProductExportFields.NAMES;
            foreach (var name in names)
            {
                var value = Consts.ProductExportFields.Val(name);
                items.Add(new ExportField
                {
                    Name = name,
                    Value = value
                });
            }

            return items;
        }

        /// <summary>
        /// 导出
        /// </summary>
        /// <param name="request"></param>
        /// <returns></returns>
        public byte[] Export(ExportRequest request)
        {
            //依据条件查询商品列表
            //导出到excel
            //下载excel
            byte[] excelContent = null;
            var dataSet = new DataSet();
            List<string> names = new List<string>();
            List<string> values = new List<string>();
            var uploadPath = string.Empty;
            var now = DateTime.Now;
            var filePath = string.Empty;

            try
            {
                GetPagingProductsRequest getPagingProductsRequest = request.ToDto<GetPagingProductsRequest>();
                getPagingProductsRequest.Page = 1;
                getPagingProductsRequest.Limit = int.MaxValue;
                getPagingProductsRequest.Name = request.ProductName;
                var pagingProducts = GetPagingProducts(getPagingProductsRequest);
                var products = pagingProducts.Entities;

                //list转datatable
                DataTable dataTable = products.ToDataTable();

                var exportFields = request.ExportField;
                if (exportFields.HasValue())
                {
                    names = exportFields.Select(p => p.Name).ToList();
                    values = exportFields.Select(p => p.Value).ToList();
                }
                dataSet.Tables.Add(GetExportDataTable(dataTable, values, names));
                if (dataSet.Tables == null || dataSet.Tables.Count == 0)
                {
                    return excelContent;
                }

                //读取配置
                var uploadSection = _configuration.GetSection("Upload");
                if (uploadSection != null)
                {
                    uploadPath = uploadSection["Path"].TrimEnd('/');
                }
                if (!Directory.Exists(uploadPath))
                {
                    Directory.CreateDirectory(uploadPath);
                }

                var fileName = string.Format("{0}_{1}.xlsx", request.TaskName, now.ToString(DateTimeTypeConst.CNDATEHOURMINUTESECONDMILLSECOND));
                filePath = string.Format("{0}/{1}", uploadPath, fileName);

                //导出excel
                _document.ExportExcel(dataSet, filePath, heads: null, hasTitleStyle: true);
                excelContent = File.ReadAllBytes(filePath);
            }
            catch (Exception ex)
            {
                _logger.LogError(ex, string.Format("导出excel时发生异常，message：{0}", ex.Message));
            }
            finally
            {
                //删除本地excel
                DeleteFile(filePath);
            }

            return excelContent;
        }

        /// <summary>
        /// 同步商品推广数据
        /// </summary>
        /// <returns></returns>
        public bool SyncProductPromote()
        {
            bool syncProductPromoteSuccess = false;
            var now = DateTime.Now;
            StringBuilder sbLog = new StringBuilder("开始同步商品推广数据，");
            Stopwatch stopwatch = Stopwatch.StartNew();

            //1，全量同步，从本地获取待同步的商品列表
            //2，调用快小店api获取商品详情
            //3，保存商品推广数据记录，先删除再新增
            var pagingProducts = _productDao.GetPagingProducts(new GetPagingProductsRequest
            {
                Status = "1",
                Page = 1,
                Limit = int.MaxValue
            });
            if (pagingProducts == null || !pagingProducts.Entities.HasValue())
            {
                sbLog.AppendFormat("无待同步的商品数据.");
                _logger.LogInformation(sbLog.ToString());
            }

            var products = pagingProducts.Entities;
            sbLog.AppendFormat("共：{0}个商品，", products.Count);
            sbLog.AppendFormat("开始同步商品推广数据，");

            int i = 0;
            int j = 0;
            foreach (var product in products)
            {
                var productId = product.ProductId;
                var distributeItemId = product.DistributeItemId;
                try
                {
                    var getProductDetailInfoResult = _kwaiXiaoDianService.GetProductDetailInfo(distributeItemId, millisecondsTimeout: 8000);
                    if (!getProductDetailInfoResult.IsSuccess)
                    {
                        _noticeService.SendServerChan(new SendServerChanRequest
                        {
                            Text = "同步商品推广数据时发生异常!",
                            Desp = getProductDetailInfoResult.ErrorMessage
                        }, isOnlyAdmin: true);
                        continue;
                    }

                    Mtp_Popularizechart_Krhu4i2eba28igfu promoteInfo = new Mtp_Popularizechart_Krhu4i2eba28igfu();//推广数据信息
                    var jObj = getProductDetailInfoResult.Data.data.data;
                    foreach (var item in jObj)
                    {
                        if (item.Key.Contains("mtp_popularize"))
                        {
                            promoteInfo = item.Value.ToObject<Mtp_Popularizechart_Krhu4i2eba28igfu>();
                        }
                    }

                    //平台下架的商品本地不删除，包括商品推广数据
                    if (promoteInfo != null && promoteInfo.fields != null && promoteInfo.fields.promoteInfo != null && promoteInfo.fields.promoteInfo.itemId == 0)
                    {
                        i++;
                        continue;
                    }

                    //商品推广数据
                    //更新商品维度的推广数据
                    product.LastUpdatedBy = -1;
                    product.LastUpdatedTime = now;
                    product.TotalOrderNum = promoteInfo.fields.promoteInfo.totalOrderNum;
                    product.TotalPv = promoteInfo.fields.promoteInfo.totalPv;
                    product.TotalPromoterNum = promoteInfo.fields.promoteInfo.totalPromoterNum;
                    _productDao.UpdateSpecificProperty(product, p => p.TotalOrderNum, p => p.TotalPv, p => p.TotalPromoterNum, p => p.LastUpdatedBy, p => p.LastUpdatedTime);

                    List<TProductPromote> productPromotes = new List<TProductPromote>();
                    foreach (var item in promoteInfo.fields.promoteInfo.promoteList)
                    {
                        var dateStr = item.dateStr;
                        var month = dateStr.Substring(0, 2);
                        var day = dateStr.Substring(2);
                        var promoteDate = string.Format("{0}-{1}-{2}", now.Year, month, day).ToDateTime();

                        productPromotes.Add(new TProductPromote
                        {
                            CreatedBy = -1,
                            CreatedTime = now,
                            LastUpdatedBy = -1,
                            LastUpdatedTime = now,
                            ProductId = productId,
                            PromoteDate = promoteDate,
                            OrderNum = item.orderNum,
                            PvNum = item.pv,
                            PromoterNum = item.promoterNum
                        });
                    }

                    //按推广日期排序
                    productPromotes = productPromotes.OrderBy(p => p.PromoteDate).ToList();

                    _productPromoteDao.Remove(p => p.ProductId == productId);
                    _productPromoteDao.Add(productPromotes);
                    j++;
                }
                catch (Exception ex)
                {
                    _logger.LogError(ex, string.Format("同步商品推广数据时发生异常，商品Id：{0}，message：{1}", productId, ex.Message));
                }
            }
            stopwatch.Stop();
            sbLog.AppendFormat("下架忽略：{0}个商品，成功同步：{1}个商品，", i, j);
            sbLog.AppendFormat("全部同步完成，共耗时：{0}秒！", stopwatch.ElapsedMilliseconds / 1000);
            _logger.LogInformation(sbLog.ToString());

            syncProductPromoteSuccess = true;
            return syncProductPromoteSuccess;
        }

        /// <summary>
        /// 获取商品SKU列表
        /// </summary>
        /// <param name="productId"></param>
        /// <returns></returns>
        public GetSKUListResponse GetSKUList(string productId)
        {
            GetSKUListResponse getSKUListResponse = new GetSKUListResponse()
            {
                ProductId = productId,
                SKUList = new List<SKUItem>()
            };
            List<SKUItem> sKUs = new List<SKUItem>();

            //读取配置
            var cacheSKUHours = _configuration["Cache.SKU.Hours"].ToInt(48);
            var cacheKey = string.Format("KwaiXiaoDian:Product:SKU:{0}", productId);
            var cacheValue = _memoryCache.Get(cacheKey);
            if (cacheValue != null)
            {
                getSKUListResponse = (GetSKUListResponse)cacheValue;
                return getSKUListResponse;
            }

            var getProductSkuInfoResult = _kwaiXiaoDianService.GetProductSkuInfo(productId, millisecondsTimeout: 1000);
            if (!getProductSkuInfoResult.IsSuccess)
            {
                _noticeService.SendServerChan(new SendServerChanRequest
                {
                    Text = "获取商品SKU时发生异常!",
                    Desp = getProductSkuInfoResult.ErrorMessage
                }, isOnlyAdmin: true);

                return getSKUListResponse;
            }

            var maxPrice = getProductSkuInfoResult.Data.data.maxPrice;
            var minPrice = getProductSkuInfoResult.Data.data.minPrice;
            getSKUListResponse.MaxPrice = ((double)maxPrice / 100).ToString("0.00");
            getSKUListResponse.MinPrice = ((double)minPrice / 100).ToString("0.00");

            foreach (var item in getProductSkuInfoResult.Data.data.skuList)
            {
                var skuDesc = item.skuDesc;
                var skuPrice = ((double)item.skuPrice / 100).ToString("0.00");

                sKUs.Add(new SKUItem
                {
                    SkuId = item.skuId.ToString(),
                    SkuDesc = skuDesc,
                    SkuPrice = skuPrice,
                    SkuDesc2 = string.Format("{0},{1}元", skuDesc, skuPrice)
                });
            }
            getSKUListResponse.SKUList = sKUs;

            //保存缓存
            _memoryCache.Set(cacheKey, getSKUListResponse, DateTimeOffset.Now.AddHours(cacheSKUHours));

            return getSKUListResponse;
        }

        /// <summary>
        /// 更新处理意见
        /// </summary>
        /// <param name="request"></param>
        /// <returns></returns>
        public Tuple<bool, string> UpdateHandleRemark(UpdateHandleRemarkRequest request, long userId)
        {
            var updateHandleRemarkSuccess = false;
            var errorMessage = string.Empty;
            var now = DateTime.Now;

            var product = _productDao.Get(request.Id);
            if (!request.HandleStatus.IsNullOrEmpty())
            {
                var handleStatusType = request.HandleStatus.ToEnum<Enums.HandleStatusType>();
                product.HandleStatus = (byte)handleStatusType;
            }
            product.Remark = request.Remark;
            product.LastUpdatedBy = userId;
            product.LastUpdatedTime = now;
            updateHandleRemarkSuccess = _productDao.Update(product);

            return new Tuple<bool, string>(updateHandleRemarkSuccess, "");
        }

        #region Private method

        /// <summary>
        /// 删除文件
        /// </summary>
        /// <param name="filePath"></param>
        /// <returns></returns>
        private bool DeleteFile(string filePath)
        {
            try
            {
                if (File.Exists(filePath))
                {
                    File.Delete(filePath);
                }

                return true;
            }
            catch
            {
                return false;
            }
        }

        /// <summary>
        /// 删除文件夹
        /// </summary>
        /// <param name="path"></param>
        /// <returns></returns>
        private bool DeleteDirectory(string path)
        {
            try
            {
                DirectoryInfo directory = new DirectoryInfo(path);
                if (directory.Exists)
                {
                    directory.Attributes = FileAttributes.Normal;
                    directory.Delete(recursive: true);
                }
                return true;
            }
            catch
            {
                return false;
            }
        }

        private DataTable GetExportDataTable(DataTable dt, List<string> Names, List<string> Titles)
        {
            for (int i = dt.Columns.Count - 1; i >= 0; i--)
            {
                var nameIndex = Names.FindIndex(c => c == dt.Columns[i].ColumnName);
                if (nameIndex < 0)
                {
                    dt.Columns.Remove(dt.Columns[i]);
                }
                else
                {
                    dt.Columns[i].ColumnName = Titles[nameIndex];
                }
            }
            for (int i = 0; i < Titles.Count; i++)
            {
                for (int j = 0; j < dt.Columns.Count; j++)
                {
                    if (dt.Columns[j].ColumnName == Titles[i])
                    {
                        dt.Columns[j].SetOrdinal(i);
                        break;
                    }
                }
            }
            return dt;
        }

        /// <summary>
        /// 依据表头和数据生成一个MarkDown表格
        /// </summary>
        /// <param name="headers"></param>
        /// <param name="data"></param>
        /// <returns></returns>
        private string GenerateMarkdownTable(List<string> headers, List<List<string>> data)
        {
            // 生成表头行
            string headerRow = "| " + string.Join(" | ", headers) + " |";

            // 生成分隔行
            string separatorRow = "| " + string.Join(" | ", headers.Select(h => "---")) + " |";

            // 生成数据行
            List<string> dataRows = new List<string>();
            foreach (var row in data)
            {
                dataRows.Add("| " + string.Join(" | ", row) + " |");
            }

            // 组合所有行
            List<string> allRows = new List<string> { headerRow, separatorRow };
            allRows.AddRange(dataRows);

            // 用换行符连接所有行
            return string.Join(Environment.NewLine, allRows);
        }


        #endregion

    }

    /// <summary>
    /// 商品信息相等比较器
    /// </summary>
    public class ProductEqualityComparer : IEqualityComparer<TProduct>
    {
        public bool Equals(TProduct x, TProduct y)
        {
            if (ReferenceEquals(x, y)) return true;
            if (ReferenceEquals(x, null)) return false;
            if (ReferenceEquals(y, null)) return false;
            if (x.GetType() != y.GetType()) return false;
            return x.LeaderId == y.LeaderId && x.ProductId == y.ProductId;
        }

        public int GetHashCode(TProduct obj)
        {
            return (obj.ProductId != null ? obj.ProductId.GetHashCode() : 0);
        }
    }
}
